package com.xijia.example.util;

import com.maxmind.geoip2.DatabaseReader;
import com.maxmind.geoip2.exception.GeoIp2Exception;
import com.maxmind.geoip2.model.CityResponse;
import com.xijia.example.manage.model.Address;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetAddress;


/**
 * 指定国家的 ip 拦截
 * @author 王松
 * @mail 1720696548@qq.com
 * @date 2024/6/20 14:34
 */
@Slf4j
public class IPUtil {

    // ipdb 存储路径
    private static DatabaseReader reader = null;

    static {
        try {
//            String daPath = "static/geoip2/GeoLite2-Country.mmdb";
            String daPath = "static/geoip2/GeoLite2-City.mmdb";
            InputStream in = getInputStreamByClasspath(daPath);
            reader = new DatabaseReader.Builder(in).build();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    /**
     * 通过 ip 获取地址信息
     * @author 王松
     * @mail 1720696548@qq.com
     * @date 2024/8/14 9:34
     */
    public static Address getAddressByIp(String ip) throws IOException, GeoIp2Exception {
        // 查询的IP地址
        InetAddress ipAddress = InetAddress.getByName(ip); // 示例IP地址
        // 获取CityResponse对象
        CityResponse response = reader.city(ipAddress);
        // 获取信息
        Address address = new Address();
        // 默认省市区
        address.setCountryCode(response.getCountry().getIsoCode());
        address.setCountryName(response.getCountry().getName());
        address.setCity(response.getCity().getName());
        address.setMostSpecificSubdivision(response.getMostSpecificSubdivision().getName());
        // 为中国时
        if (response.getCountry().getIsoCode().equals("CN")) {
            address.setCountryName(response.getCountry().getNames().get("zh-CN"));
            address.setMostSpecificSubdivision(response.getMostSpecificSubdivision().getNames().get("zh-CN"));
            address.setCity(response.getCity().getNames().get("zh-CN"));
        }
        address.setCountryNames(response.getCity().getNames());
        address.setMostSpecificSubdivisionNames(response.getMostSpecificSubdivision().getNames());
        address.setCityNames(response.getCity().getNames());
        // 其他信息
        address.setLatitude(response.getLocation().getLatitude());
        address.setLongitude(response.getLocation().getLongitude());
        address.setAccuracyRadius(response.getLocation().getAccuracyRadius());
        address.setPostalCode(response.getPostal().getCode());
        address.setDomain(response.getTraits().getDomain());

        // 省市区数据为 null 时设置为空字符串
        if (address.getCountryName() == null) {
            address.setCountryName("");
        }
        if (address.getMostSpecificSubdivision() == null) {
            address.setMostSpecificSubdivision("");
        }
        if (address.getCity() == null) {
            address.setCity("");
        }
        return address;
    }

    /**
     * 获取用户真实IP地址，不使用request.getRemoteAddr()的原因是有可能用户使用了代理软件方式避免真实IP地址,
     * 可是，如果通过了多级反向代理的话，X-Forwarded-For的值并不止一个，而是一串IP值
     *
     * @return ip
     */
    public static String getIp(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        String unknown = "unknown";
        if (ip != null && ip.length() != 0 && !unknown.equalsIgnoreCase(ip)) {
            // 多次反向代理后会有多个ip值，第一个ip才是真实ip
            if (ip.contains(",")) {
                ip = ip.split(",")[0];
            }
        }
        if (ip == null || ip.length() == 0 || unknown.equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || unknown.equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || unknown.equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
        }
        if (ip == null || ip.length() == 0 || unknown.equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (ip == null || ip.length() == 0 || unknown.equalsIgnoreCase(ip)) {
            ip = request.getHeader("X-Real-IP");
        }
        if (ip == null || ip.length() == 0 || unknown.equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }


    /**
     * 文件获取  (获取 resources 下的文件, 支持打 jar 后在服务器中获取)
     * 如需 BufferedReader, 自行使用  new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8))
     *
     * @author wangsong
     * @email 1720696548@qq.com
     * @date 2022/12/22 0022 21:06
     * @version 1.0.0
     */
    public static InputStream getInputStreamByClasspath(String path) {
        Resource resource = new ClassPathResource(path);
        try {
            return resource.getInputStream();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}
